package com.yunbiao.ybbusstopplate.serialport.agreement;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.blankj.utilcode.util.FileIOUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.UiMessageUtils;
import com.yunbiao.ybbusstopplate.bean.SiteInfoBean;
import com.yunbiao.ybbusstopplate.utils.BytesUtils;
import com.yunbiao.ybbusstopplate.utils.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import tp.xmaihh.serialport.bean.ComBean;

public class HYPortAgreement extends BaseAgreement{
    private static final String TAG = "HYPortAgreement";
    private static HYPortAgreement hyPortAgreement;
    private AgreementDataTool dataTool;
    public static HYPortAgreement getInstance(){
        if (hyPortAgreement==null){
            hyPortAgreement=new HYPortAgreement();
        }
        return hyPortAgreement;
    }
    private HYPortAgreement(){
        dataTool=new AgreementDataTool();
        //通信数据
        dataTool.setDataReceive(new AgreementDataTool.AgreementDataReceive() {
            @Override
            public void onDataReceive(byte[] datas) {
                if (datas==null||datas.length<=0){
                    return;
                }
                choiseData(datas);
            }
        });
    }

    public synchronized void anilzData(byte[] datas){
        try {
            if (datas==null||datas.length<=0){
                return;
            }

            byte startByte = datas[0];
            if (startByte==0x24){
                dataTool.setSHex("24");
                dataTool.setEHex("0d");
            } else if (startByte==0x3a){
                dataTool.setSHex("3a");
                dataTool.setEHex("11");
            } else if(startByte == 0x1E){
                dataTool.setSHex("1e");
                dataTool.setEHex("1f");
            }
            dataTool.handleData(datas);
        } catch (Exception e) {
            e.printStackTrace();
//            if (agreementListener!=null){
//                agreementListener.agreementFailed();
//            }
        }
    }

    //数据处理
    private void choiseData(byte[] datas){
        String hex = BytesUtils.bytesToHex(datas);
        System.out.println(TAG+"---->"+hex);
        byte startByte = datas[0];
        if (startByte==0x24){
            byte order = datas[8];
            if (order == (byte)0x5a) {
                //站点列表
                getSiteList(datas);
            } else if(order == (byte)0x54){
                correctTime(datas);
            }
        }else if (startByte==0x3a){
            //到、离站信息
            getSiteState(datas);
        } else if(startByte == 0x1E){
            //线路信息
            getSiteInfo(datas);
        }
    }

    // 24
    // 26
    // 30303030
    // 3030
    // 54
    // 30
    // 3230313330373239313633313230
    // 31
    // 53535353
    private void correctTime(byte[] datas){
//        byte[] bytes = BytesUtils.SubByte(datas, 10, 14);
//        String time = StringUtils.hexStringToString(BytesUtils.bytesToHex(bytes));
//        d( "correctTime: " + time);
//
//        int year = Integer.parseInt(time.substring(0, 4));//年
//        int month = Integer.parseInt(time.substring(4,6));//月
//        int day = Integer.parseInt(time.substring(6,8));//日
//        int hours = Integer.parseInt(time.substring(8,10));//日
//        int minutes = Integer.parseInt(time.substring(10,12));//日
//        int seconds = Integer.parseInt(time.substring(12));//日
//        int[] ints = {year, month, day, hours, minutes,seconds};
//        Log.d(TAG, "correctTime: " + Arrays.toString(ints));
//        UiMessageUtils.getInstance().send(777,ints);
        // 3230313330373239313633313230
    }

    public void getSiteInfo(byte[] datas){
        d( "线路信息");

        //取出数据长度
        byte[] LENGTH_BYTES = BytesUtils.SubByte(datas, 6, 2);
        int length = BytesUtils.hex16to10(BytesUtils.bytesToHex(LENGTH_BYTES));
        //取出数据帧
        byte[] DATA_FRAME_BYTES = BytesUtils.SubByte(datas, 8, length);
        d("数据帧：" + BytesUtils.bytesToHex(DATA_FRAME_BYTES));
        //线路信息数据
        byte[] LINE_INFO_BYTES = BytesUtils.SubByte(DATA_FRAME_BYTES, 7, DATA_FRAME_BYTES.length - 7);
        d("线路信息数据：" + BytesUtils.bytesToHex(LINE_INFO_BYTES));

        Queue<Byte> byteQueue = new LinkedList<>();
        for (byte line_info_byte : LINE_INFO_BYTES) {
            byteQueue.add(line_info_byte);
        }

        String[] lineInfoArray = new String[3];
        String frameTag = "";
        int tag = 1,dataLength = 1;
        while (!byteQueue.isEmpty()) {
            byte[] newBytes;
            switch (tag) {
                case 1:
                    tag = 2;
                    dataLength = 1;
                    newBytes = new byte[dataLength];
                    for (int i = 0; i < newBytes.length; i++) {
                        newBytes[i] = byteQueue.poll();
                    }
                    frameTag = BytesUtils.bytesToHex(newBytes);
                    break;
                case 2:
                    tag = 3;
                    dataLength = 1;
                    newBytes = new byte[dataLength];
                    for (int i = 0; i < newBytes.length; i++) {
                        newBytes[i] = byteQueue.poll();
                    }
                    dataLength = BytesUtils.hex16to10(BytesUtils.bytesToHex(newBytes));
                    break;
                case 3:
                    tag = 1;
                    newBytes = new byte[dataLength];
                    for (int i = 0; i < newBytes.length; i++) {
                        newBytes[i] = byteQueue.poll();
                    }
                    String s = StringUtils.hexStringToString(BytesUtils.bytesToHex(newBytes));
                    switch (frameTag) {
                        case "01":
                            lineInfoArray[0] = s;
                            lineName = s;
                            break;
                        case "02":
                            lineInfoArray[1] = s;
                            break;
                        case "03":
                            lineInfoArray[2] = s;
                            break;
                    }
                    break;
            }
        }

        d( Arrays.toString(lineInfoArray));

        if (agreementListener!=null){
            agreementListener.onLineInfoResult(lineInfoArray);
        }
    }

    private String lineName;
    private final ArrayList<String> upList=new ArrayList<>();
    private final ArrayList<String> downList=new ArrayList<>();
    private void getSiteList(byte[] datas){
        System.out.println(TAG+"---->车站列表");
        //上、下行
        String upDownFlag = StringUtils.hexStringToString(BytesUtils.byteToHex(datas[9]));

        //当前包 01-99
        int current = Integer.parseInt(StringUtils.hexStringToString(BytesUtils.bytesToHex(new byte[]{datas[10],datas[11]})));

        //包总数
        int total = Integer.parseInt(StringUtils.hexStringToString(BytesUtils.bytesToHex(new byte[]{datas[12], datas[13]})));

        //站点数据
        String site = StringUtils.hexStringToString(BytesUtils.bytesToHex(BytesUtils.SubByte(datas, 14, datas.length-19)));
        String[] siteArray = site.split("#");
        for (String s : siteArray) {
            d( "站点：" + s + " --- " + upDownFlag);
        }

        //0：上行
        if("0".equals(upDownFlag)){
            //如果是第一包，则清除后再添加
            if(current == 1){
                upList.clear();
            }
            upList.addAll(Arrays.asList(siteArray));
            if(current == total){
                //上行
                if (agreementListener!=null){
                    agreementListener.onSiteListResult(upList);
                }
            }
        } else if("1".equals(upDownFlag)){
            if (current == 1){
                downList.clear();
            }
            downList.addAll(Arrays.asList(siteArray));
        }
    }

    private String mUpDownFlag;
    private void getSiteState(byte[] datas){
        System.out.println(TAG+"---->到、离站信息");

        byte UP_DOWN_FLAG = datas[6];//上、下行
        String upDownFlag = BytesUtils.byteToHex(UP_DOWN_FLAG);

        if(TextUtils.isEmpty(mUpDownFlag) || !TextUtils.equals(upDownFlag,mUpDownFlag)){
            d("标识为空或与数据中不同，切换上下行");
            mUpDownFlag = upDownFlag;

            String start = "",end = "";
            //上行
            if (TextUtils.equals("00",mUpDownFlag)) {
                start = upList.isEmpty() ? "" : upList.get(0);
                end = upList.isEmpty() ? "" : upList.get(upList.size() - 1);
                //上行
                if (agreementListener!=null){
                    agreementListener.onLineInfoResult(new String[]{lineName,start,end});
                    agreementListener.onSiteListResult(upList);
                }
            }
            //下行
            else if(TextUtils.equals("ff",mUpDownFlag)){
                if(downList.isEmpty()){
                    //反转上下数据
                    List<String> upSiteList = new ArrayList<>(upList);
                    Collections.reverse(upSiteList);
                    downList.addAll(upSiteList);
                    d("下行数据为空，反转上行数据：" + upList);
                }
                start = downList.isEmpty() ? "" : downList.get(0);
                end = downList.isEmpty() ? "" : downList.get(downList.size() - 1);
                //下行
                if (agreementListener!=null){
                    agreementListener.onLineInfoResult(new String[]{lineName,start,end});
                    agreementListener.onSiteListResult(downList);
                }
            }
        }

        //进出站标识
        byte IN_OUT = datas[3];
        String inOut = BytesUtils.byteToHex(IN_OUT);

        //当前站点
        byte STATION_INDEX = datas[4];
        int inStationIndex = Integer.valueOf(BytesUtils.byteToHex(STATION_INDEX), 16);

        //下行
        int currIndex;
        if(TextUtils.equals("ff",mUpDownFlag)){
            currIndex = inStationIndex - 1;
        }
        //上行
        else {
            currIndex = upList.size() - inStationIndex;
        }

        //到离站信息
        SiteInfoBean siteInfoBean = new SiteInfoBean();
        siteInfoBean.setSiteName("");
        siteInfoBean.setStutas("22".equals(inOut) ? 1 : 0);
        siteInfoBean.setIndex("22".equals(inOut) ? currIndex : (currIndex + 1));
        if (agreementListener!=null){
            agreementListener.onSiteTipResult(siteInfoBean);
        }
    }

    private void d(String log){
        LogUtils.d(TAG,log);
//        Log.d(TAG, log);
    }



    public void testList(){
        new Thread(() -> {

            StringBuilder stringBuilder = new StringBuilder();

            //第一包
            File file1 = new File(Environment.getExternalStorageDirectory(), "HY1.txt");
            List<String> strings1 = FileIOUtils.readFile2List(file1);
            for (String s : strings1) {
                String trim = s.replaceAll("0x", "").replaceAll(" ", "").trim();
                stringBuilder.append(trim);
            }
            d("第一包：" + stringBuilder.toString());
            byte[] bytes = BytesUtils.hexToByteArray(stringBuilder.toString());
            anilzData(bytes);
            stringBuilder.setLength(0);

            //第二包
            File file2 = new File(Environment.getExternalStorageDirectory(), "HY2.txt");
            List<String> strings2 = FileIOUtils.readFile2List(file2);
            for (String s : strings2) {
                String trim = s.replaceAll("0x", "").replaceAll(" ", "").trim();
                stringBuilder.append(trim);
            }
            d("第二包：" + stringBuilder.toString());
            bytes = BytesUtils.hexToByteArray(stringBuilder.toString());
            anilzData(bytes);
            stringBuilder.setLength(0);

            //第三包
            File file3 = new File(Environment.getExternalStorageDirectory(), "HY3.txt");
            List<String> strings3 = FileIOUtils.readFile2List(file3);
            for (String s : strings3) {
                String trim = s.replaceAll("0x", "").replaceAll(" ", "").trim();
                stringBuilder.append(trim);
            }
            d("第三包：" + stringBuilder.toString());
            bytes = BytesUtils.hexToByteArray(stringBuilder.toString());
            anilzData(bytes);
            stringBuilder.setLength(0);

            //第四包
            File file4 = new File(Environment.getExternalStorageDirectory(), "HY4.txt");
            List<String> strings4 = FileIOUtils.readFile2List(file4);
            for (String s : strings4) {
                String trim = s.replaceAll("0x", "").replaceAll(" ", "").trim();
                stringBuilder.append(trim);
            }
            d("第四包：" + stringBuilder.toString());
            bytes = BytesUtils.hexToByteArray(stringBuilder.toString());
            anilzData(bytes);
            stringBuilder.setLength(0);

            //第五包
            File file5 = new File(Environment.getExternalStorageDirectory(), "HY5.txt");
            List<String> strings5 = FileIOUtils.readFile2List(file5);
            for (String s : strings5) {
                String trim = s.replaceAll("0x", "").replaceAll(" ", "").trim();
                stringBuilder.append(trim);
            }
            d("第五包：" + stringBuilder.toString());
            bytes = BytesUtils.hexToByteArray(stringBuilder.toString());
            anilzData(bytes);
            stringBuilder.setLength(0);

        }).start();
    }


    public void testInfo(){
        // 1E 60 包头
        // FF 目标地址
        // 02 源地址
        // 06 消息帧
        // 08 消息帧流水号
        // 00 22 消息帧长度
        // 1B 数据帧1标识
        // 00 1F 数据帧1长度
        // 00 线路序号
        // 00 显示方式
        // 00 数据压缩
        // 00 空调、K字控制
        // 01 数据类型01线路名
        // 03 线路号长度
        // 31 C2 B7
        // 02 数据类型左站名
        // 08 左站名长度
        // B9 AB BD BB D7 DC D5 BE
        // 03 数据类型右站名
        // 0A 右站名长度
        // C2 CC D0 C4 C5 C9 B3 F6 CB F9
        // FB
        // 1F
//        String s = "1E 60 FF 02 06 08 00 22 1B 00 1F 00 00 00 00 01 03 31 C2 B7 02 08 B9 AB BD BB D7 DC D5 BE 03 0A C2 CC D0 C4 C5 C9 B3 F6 CB F9 FB 1F".replaceAll(" ","");
//        Log.e(TAG, "testInfo: 数据：" + s);
//        byte[] bytes = BytesUtils.hexToByteArray(s);
//        anilzData(bytes);

//        String s = "24263030303030305430323031333037323931363331323031535353530D";
//        byte[] bytes = BytesUtils.hexToByteArray(s);
//        anilzData(bytes);

        new Thread(() -> {
            File file = new File(Environment.getExternalStorageDirectory(),"123123123.txt");
            List<String> strings = FileIOUtils.readFile2List(file);
            for (String string : strings) {
                if(!string.contains("<---")){
                    continue;
                }
                String s = string.split("<---")[1];
                Log.d(TAG, "testInfo: " + s);
                byte[] bytes = BytesUtils.hexToByteArray(s);
                anilzData(bytes);
            }
        }).start();

    }

    int index = 1;
    String upDown = "ff";
    String inOut = "22";
    public void testInOut(){
        // 0x3a 0x3a 0x1c 0x22 0x01 0x25 0xff 0x11 0x11
        //   标识头   站数  进站  第几  线号 下行    结束
        String s = Integer.toHexString(index);
        while (s.length() < 2) {
            s = "0" + s;
        }
        String hex = "3a3a1c" + inOut + s + "25" + upDown + "1111";
        Log.d(TAG, "数据：站点序号：" + inOut + " --- " + index + " --- " + upDown);

        byte[] bytes = BytesUtils.hexToByteArray(hex);
        anilzData(bytes);

        //根据上下行递增或递减索引
        if("ff".equals(upDown)){
            //进站才修改索引
            if("22".equals(inOut)){
                inOut = "11";
            } else if("11".equals(inOut)){
                inOut = "22";
                index ++;
            }
        } else if("00".equals(upDown)){
            //进站才修改索引
            if("22".equals(inOut)){
                inOut = "11";
            } else if("11".equals(inOut)){
                inOut = "22";
                index --;
            }
        }

        //如果大于下行列表数量则切换为上行
        if(index > downList.size()){
            index = upList.size();
            upDown = "00";
            Log.d(TAG, "testInOut: ----------------------");
        } else if(index < 1){
            index = 1;
            upDown = "ff";
            Log.d(TAG, "testInOut: ----------------------------");
        }
    }
}
